// ======================================================================
// \title  Hash.hpp
// \author dinkel
// \brief  hpp file for Hash class
//
// \copyright
// Copyright 2009-2015, by the California Institute of Technology.
// ALL RIGHTS RESERVED.  United States Government Sponsorship
// acknowledged.
//
// ======================================================================

#ifndef UTILS_HASH_HPP
#define UTILS_HASH_HPP

#include <Utils/Hash/HashBuffer.hpp>
#include "Fw/Types/StringType.hpp"

namespace Utils {

//! \class Hash
//! \brief A generic interface for creating and comparing hash values
//!
class Hash {
  public:
    // ----------------------------------------------------------------------
    // Types
    // ----------------------------------------------------------------------
  public:
    // ----------------------------------------------------------------------
    // Construction and destruction
    // ----------------------------------------------------------------------

    //! Construct a Hash object
    //!
    Hash();

    //! Destroy a Hash object
    //!
    ~Hash();

  public:
    // ----------------------------------------------------------------------
    // Public static methods
    // ----------------------------------------------------------------------

    //! Create a hash value all at once from raw data
    //! \param data: pointer to start of data
    //! \param len: length of the data
    //! \param buffer: filled with resulting hash value
    static void hash(const void* data, const FwSizeType len, HashBuffer& buffer);

  public:
    // ----------------------------------------------------------------------
    // Public instance methods
    // ----------------------------------------------------------------------

    //! Initialize a Hash object for incremental hash computation
    //!
    void init();

    //! Set hash value to specified value
    //!
    void setHashValue(HashBuffer& value  //! Hash value
    );

    //! Update an incremental computation with new data
    //! \param data: pointer to start of data to add to hash calculation
    //! \param len: length of data to add to hash calculation
    void update(const void* const data, const FwSizeType len);

    //! Finalize an incremental computation and return the result
    //!
    void final(HashBuffer& buffer  //! The result
    );

    //! Finalize an incremental computation and return the result
    //!
    void final(U32& hashvalue);

    //! Get the file extension for the supported hash type
    //! E.g., could return "SHA256"
    //!
    static const char* getFileExtensionString();

    //! Add the extension for the supported hash type
    //!
    static void addFileExtension(const Fw::ConstStringBase& baseName,  //!< The base name
                                 Fw::StringBase& extendedName          //!< The extended name
    );

    //! Get the length of the file extension string
    //!
    static FwSizeType getFileExtensionLength();

  private:
    // ----------------------------------------------------------------------
    // Private member variables
    // ----------------------------------------------------------------------

    //! The hash handle
    //!
    HASH_HANDLE_TYPE hash_handle;
};

}  // namespace Utils

#endif
